//
//  ScancodeViewController.swift
//  app路由
//
//  Created by zhaoguoteng on 2020/4/28.
//  Copyright © 2020 zhaoguoteng. All rights reserved.
//

import UIKit
import FMDB
import AVFoundation

class ScancodeViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
    
    @IBOutlet var scanImgView: UIImageView!
    var dismissBlock: (() -> Void)?
    
    /// 会话 session
    let session: AVCaptureSession = {
       let session = AVCaptureSession.init()
       if session.canSetSessionPreset(.high){
           session.sessionPreset = .high
       }
       return session
    }()
    
    /// 预览层
    let preLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer.init()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        scanImgView.alpha = 0.4
        
        let status = AVCaptureDevice.authorizationStatus(for: .video)
        
        if status != .authorized {
            
            AVCaptureDevice.requestAccess(for: .video) { _ in
                
            }
        }
        
        // 捕捉设备
        guard let device = AVCaptureDevice.default(for: .video)  else {
           return
        }
        
        do {
            // 输入
            let input = try AVCaptureDeviceInput.init(device: device)

            /// 输出
            let outPut: AVCaptureMetadataOutput = {
                let outPut = AVCaptureMetadataOutput.init()
                outPut.connection(with: .metadata)
                return outPut
            }()
            
            // 设代理
            outPut.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            // 指定预览层的捕捉会话
            preLayer.session = session
            
            // 捕捉会话加入input和output
            if session.canAddInput(input) && session.canAddOutput(outPut) {
                      session.addInput(input)
                      session.addOutput(outPut)
                      // 设置元数据处理类型(注意, 一定要将设置元数据处理类型的代码添加到  会话添加输出之后)
                      outPut.metadataObjectTypes = [.ean13, .ean8, .upce, .code39, .code93, .code128, .code39Mod43, .qr]
                  }
            
             // 添加预览图层
            let flag = view.layer.sublayers?.contains(preLayer)
            if flag == false || flag == nil {
                  preLayer.frame = view.bounds
                  view.layer.insertSublayer(preLayer, at: 0)
            }

            // 启动会话
            session.startRunning()
        } catch  {
            print(error)
        }
    }

    func save(list: [Route]?) {
        
        guard let db = SqliteManager.shareDB else {
            return
        }
        
        if !db.isOpen {
            db.open()
        }
        
        if let list = list {
            db.beginTransaction()
            for route in list {
                guard let name = route.name, let url = route.url else {
                    print("数据不完整")
                    return
                }
                
                do {
                    try db.executeUpdate("insert into routes (name, url, remark, date) values ('\(name)', '\(url)', '\(route.remark ?? "")', '\(Date().timeIntervalSince1970)')", values: nil)
                } catch {
                    fatalError(error.localizedDescription)
                }
            }
            db.commit()
        }
        
        db.close()
    }
    
    func saveLog(json: String?) {
        
        guard let dbQueue = SqliteManager.shareDBQ else {
            return
        }
        
        if let json = json {
            dbQueue.inDatabase { db in
                do {
                try db.executeUpdate("insert into scanlog (json, date) values ('\(json)', '\(Date().timeIntervalSince1970)')", values: nil)
                } catch {
                    fatalError(error.localizedDescription)
                }
            }
        }
    }
    
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        session.stopRunning()
        
        var resultStrs = [String]()
            for obj in metadataObjects {
                guard let codeObj = obj as? AVMetadataMachineReadableCodeObject else {
                    return
                }
                resultStrs.append(codeObj.stringValue ?? "")
            }
        
        if let json = resultStrs.first {
            let alert = UIAlertController(title: "扫码结果", message: json, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "取消", style: .destructive, handler: nil))
            alert.addAction(UIAlertAction(title: "确定", style: .default, handler: { [weak self] (_) in
                
                guard let self = self else {
                    return
                }
                
                let jsonData = json.data(using: .utf8)
                let list = Route.routes(jsonData: jsonData)
                self.save(list: list)
                self.saveLog(json: json)
                self.dismiss(animated: true, completion: nil)
                if let dismissBlock = self.dismissBlock {
                    dismissBlock()
                }
            }))
            
            present(alert, animated: true, completion: nil)
        }
    }
    
    @IBAction func closeAction() {
        dismiss(animated: true, completion: nil)
    }
}
